package cn.iocoder.devlop.module.annual.report.aspect;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.iocoder.devlop.module.annual.report.annotations.PushToApi;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * 推送数据信息切面
 *
 * @author Euan
 * @since 2024/1/20
 */
@Aspect
@Component
@Slf4j
public class PushDbInfoAspect {
    @Pointcut("@annotation(cn.iocoder.devlop.module.annual.report.annotations.PushToApi)")
    public void pushToApiPointcut() {
        // 定义切点，匹配带有 @PushToApi 注解的方法
    }

    @Around("pushToApiPointcut()")
    public Object aroundSaveOrUpdate(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        // 获取方法上的注解
        PushToApi pushToApiAnnotation = getPushToApiAnnotation(proceedingJoinPoint);

        // 继续执行被切面的方法
        Object result = proceedingJoinPoint.proceed();

        // 访问注解的属性
        if (pushToApiAnnotation == null || !pushToApiAnnotation.enable()) {
            log.info("未开启同步,{}", result.getClass());
            return result;
        }


        pushDataToApi(result, pushToApiAnnotation);
        return result;
    }

    private PushToApi getPushToApiAnnotation(JoinPoint joinPoint) throws NoSuchMethodException {
        // 获取方法上的 @PushToApi 注解
        return Arrays.stream(joinPoint.getTarget().getClass().getMethod(joinPoint.getSignature().getName(),
                                ((MethodSignature) joinPoint.getSignature()).getParameterTypes())
                        .getAnnotationsByType(PushToApi.class))
                .findFirst()
                .orElse(null);
    }

    private void pushDataToApi(Object result, PushToApi pushToApi) {
        JSONObject data = JSONUtil.parseObj(result);
        String year = data.getStr("ancheyear", "2023");
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("type", pushToApi.type());
        jsonObject.set("target", pushToApi.target() + "_" + year);
        jsonObject.set("data", result);
        HttpResponse execute = HttpRequest.post(pushToApi.value()).body(jsonObject.toString()).execute();
        if (execute.getStatus() != HttpStatus.HTTP_OK) {
            log.error("同步失败");
        }
    }
}
